package org.ricks.log;

import org.ricks.log.message.Message;
import org.ricks.log.pattern.PatternFormatter;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author chenwei
 * @Description: 一次日志事件，一次记录
 * @date 2023/1/916:19
 */
public class LogEvent {

    /**
     * 日志发生的时间
     */
    private final LocalDateTime eventTime;
    /**
     * 这行日志的等级
     */
    private final Level level;
    /**
     * 线程名称
     */
    private final String threadName;
    /**
     * 日志内容
     */
    protected final Message message;

    /**
     * 文件名称
     */
    private String fileName;

    private String className;

    private String methodName;

    /**
     * 当前行号
     */
    private int lineNumber;

    LogEvent(Level level, Message message) {
        this.eventTime = LocalDateTime.now();
        this.level = level;

        final Thread thread = Thread.currentThread();
        this.threadName = thread.getName();

        this.message = message;
        //获取StackTraceElement 性能有影响，一千万次 log 带上StackTraceElement信息耗时30-50秒左右。如果不加上StackTraceElement异步投递只需要5秒
        StackTraceElement stackTraceElement = RuntimeProvider.getCallerStackTraceElement(6);
        if(stackTraceElement != null) {
            className = stackTraceElement.getClassName();
            methodName = stackTraceElement.getMethodName();
            fileName = stackTraceElement.getFileName();
            lineNumber = stackTraceElement.getLineNumber();
        }
    }

    public LocalDateTime getEventTime() {
        return eventTime;
    }

    public Level getLevel() {
        return level;
    }

    public char[] build(List<PatternFormatter> formatterList) {
        StringBuilder sb = new StringBuilder();
        for (PatternFormatter formatter : formatterList) {
            formatter.format(this, sb);
        }

        final char[] result = new char[sb.length()];
        sb.getChars(0, result.length, result, 0);
        return result;
    }

    public String getThreadName() {
        return threadName;
    }

    public Message getMessage() {
        return message;
    }

    public String getFileName() {
        return fileName;
    }

    public int getLineNumber() {
        return lineNumber;
    }

    public String getClassName() {
        return className;
    }

    public String getMethodName() {
        return methodName;
    }
}
